#ifndef XG_HTTPREQUEST_H
#define XG_HTTPREQUEST_H
////////////////////////////////////////////////////////
#include "HttpBase.h"
#include "HttpFrame.h"

#define HTTP_REQHDR_ENDSTR		"\r\n\r\n"
#define HTTP_REQHDR_ENDSTR_LEN		4

class HttpRequest : public IHttpRequest
{
	friend class HttpServer;
	friend class HttpStream;
	friend class HttpResponse;
	friend class HttpRequestItem;

protected:
	HttpHeadNode node;
	HttpDataNode data;

	bool parseBoundary();
	int init(const HttpFrame& frame);
	bool parseHeader(const char* msg);
	bool parseHeader(const char* msg, int len);
	int init(Socket* sock, SmartBuffer& data, int& readed, bool tryread);

public:
	void clear();
	string toString() const;
	SmartBuffer toBuffer() const;
	string getDataString() const;
	bool setCookie(const string& val);
	string getCookie(const string& key) const;
	bool setParameter(const string& key, const string& val);
	bool setDataValue(const string& key, const string& val);
	bool setHeadValue(const string& key, const string& val);
	void init(const string& path, E_HTTP_METHOD method = eUNKNOWN, bool simplify = false);

	bool isMobile() const;
	string getHeadString() const;
	bool setContentType(const string& val);
	string getDataValue(const string& key) const;
	string getHeadValue(const string& key) const;
	int getParameterKeys(vector<string>& vec) const;
	SmartBuffer getResult(sp<Socket> sock, bool decode = true, int timeout = SOCKET_CONNECT_TIMEOUT) const;
	sp<HttpResponse> getResponse(sp<Socket> sock, bool decode = true, int timeout = SOCKET_CONNECT_TIMEOUT) const;
	SmartBuffer getResult(const string& host, int port = 0, bool crypted = false, bool decode = true, int timeout = SOCKET_CONNECT_TIMEOUT) const;
	sp<HttpResponse> getResponse(const string& host, int port = 0, bool crypted = false, bool decode = true, int timeout = SOCKET_CONNECT_TIMEOUT) const;

	HttpRequest()
	{
	}
	HttpRequest(const string& path)
	{
		init(path);
	}
	void setHeadHost(const string& host, int port = 0)
	{
		setHeadValue("Host", port <= 0 || port == 80 || port == 443 ? host : host + ":" + stdx::str(port));
	}
	template<class DATA_TYPE> bool setParameter(const string& key, const DATA_TYPE& val)
	{
		return setDataValue(key, stdx::str(val));
	}

	static string GetUserAgent()
	{
		return Process::GetParam("HTTPREQUEST_USERAGENT");
	}
	static void SetUserAgent(const string& val)
	{
		Process::SetParam("HTTPREQUEST_USERAGENT", val);
	}

	static string ParsePath(const string& url, string& param);
	static bool GetInfoFromURL(const string& url, string& host, string& path, string& ip, int& port, bool& crypted);
};
////////////////////////////////////////////////////////
#endif